import { ref, reactive } from 'vue'
import type { Ref } from 'vue'
import { cloneDeep } from 'lodash-es'
import type { PaginationProps } from 'naive-ui'
import { useBoolean, useHookTable } from '@/hooks/base'

type TableData = {
  id: number
}

export const useTable = (config: any) => {
  const { apiFn, apiParams, immediate } = config

  const { loading, data, empty, getData, searchParams, updateSearchParams, resetSearchParams } =
    useHookTable({
      apiFn,
      apiParams,
      immediate,
      transformer: (res: any) => {
        const { records = [], current = 1, size = 10, pages = 1 } = res.data || {}
        return {
          data: records,
          pageNum: current,
          pageSize: size,
          pageCount: pages
        }
      },
      onFetched: async (transformed) => {
        const { pageNum, pageSize, pageCount } = transformed

        updatePagination({
          page: pageNum,
          pageSize,
          pageCount
        })
      }
    })

  const pagination: PaginationProps = reactive({
    page: 1,
    pageSize: 10,
    pageCount: 1,
    showSizePicker: true,
    pageSizes: [10, 15, 20, 25, 30],
    onUpdatePage: async (page: number) => {
      pagination.page = page

      updateSearchParams({
        page: page,
        size: pagination.pageSize
      })

      await getData()
    },
    onUpdatePageSize: async (pageSize: number) => {
      pagination.pageSize = pageSize
      pagination.page = 1

      updateSearchParams({
        page: pagination.page,
        size: pageSize
      })

      await getData()
    }
  })

  const updatePagination = (update: Partial<PaginationProps>) => {
    Object.assign(pagination, update)
  }

  return {
    loading,
    data,
    empty,
    getData,
    pagination,
    searchParams,
    updateSearchParams,
    resetSearchParams
  }
}

export const useTableOperate = <T extends TableData>(
  data: Ref<T[]>,
  getData: () => Promise<void>
) => {
  const { bool: drawerVisible, setTrue: openDrawer, setFalse: closeDrawer } = useBoolean()

  const operateType = ref('add')

  const handleAdd = () => {
    operateType.value = 'add'
    openDrawer()
  }

  const editingData: Ref<T | null> = ref(null)
  const handleEdit = (id: number) => {
    operateType.value = 'edit'
    const findItem = data.value.find((item) => item.id === id) || null
    editingData.value = cloneDeep(findItem)
    openDrawer()
  }

  const checkedRowKeys = ref<number[]>([])

  const onBatchDeleted = async () => {
    window.$message?.success('批量删除成功')
    checkedRowKeys.value = []

    await getData()
  }

  const onDeleted = async (id: number) => {
    window.$message?.success('删除成功')
    await getData()
  }

  return {
    drawerVisible,
    openDrawer,
    closeDrawer,
    operateType,
    editingData,
    handleEdit,
    handleAdd,
    checkedRowKeys,
    onDeleted,
    onBatchDeleted
  }
}
